home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / PB_212.ZIP / PB212SDK.DOC < prev    next >
Text File  |  1995-09-09  |  69KB  |  2,048 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.       ▒▒▒▒▒▒▒▒▒▄                 ▒▒▒▒▒▒▒▒▒▄
  12.        ▒▒█▀▀▀▒▒█                  ▒▒█▀▀▀▒▒█
  13.        ▒▒█   ▒▒█ ▒▒▒▒▒▒▄ ▒▒▒▒▒▒▄  ▒▒█   ▒▒█ ▒▒▒▒▒▒▄ ▒▒▒▒▒▒▄ ▒▒▒▒▒▒▄ ▒▒▒▒▒▒▒▄
  14.        ▒▒▒▒▒▒▒▒█ ▒▒█▀▒▒█ ▒▒█▀▒▒█  ▒▒▒▒▒▒▒█▀ ▒▒█▀▒▒█ ▒▒█▀▒▒█ ▒▒█▀▒▒█  ▒▒█▀▒▒█
  15.        ▒▒█▀▀▀▀▀▀ ▒▒▒▒▒▒█ ▒▒█ ▒▒█  ▒▒█▀▀▀▒▒█ ▒▒█ ▒▒█ ▒▒▒▒▒▒█ ▒▒▒▒▒▒█  ▒▒█ ▒▒█
  16.        ▒▒█       ▒▒█▒▒█▀ ▒▒█ ▒▒█  ▒▒█   ▒▒█ ▒▒█ ▒▒█ ▒▒█▀▒▒█ ▒▒█▒▒█▀  ▒▒█ ▒▒█
  17.       ▒▒▒▒█      ▒▒█ ▒▒█ ▒▒▒▒▒▒█ ▒▒▒▒▒▒▒▒▒█ ▒▒▒▒▒▒█ ▒▒█ ▒▒█ ▒▒█ ▒▒█ ▒▒▒▒▒▒▒█
  18.        ▀▀▀▀       ▀▀  ▀▀  ▀▀▀▀▀▀  ▀▀▀▀▀▀▀▀▀  ▀▀▀▀▀▀  ▀▀  ▀▀  ▀▀  ▀▀  ▀▀▀▀▀▀▀
  19.  
  20.                            "The Choice of Professionals"
  21.  
  22.  
  23.                              Software Developer's Kit
  24.                                    Version 2.12
  25.  
  26.                              ++ September 9 , 1995 ++
  27.  
  28.  
  29.                    Copyright (c) 1990-1995 Philippe Leybaert
  30.                               All rights reserved
  31.  
  32.  
  33.  
  34.         ╒══════════════════════════════════════════════════════════════════╕
  35.         │░░░░░░░░ PROBOARD SOFTWARE DEVELOPMENT KIT VERSION 2.12 ░░░░░░░░░░│
  36.         ╘══════════════════════════════════════════════════════════════════╛
  37.  
  38.  
  39.          Included with ProBoard is a C library that allows you to write
  40.          your own extensions to ProBoard in C or C++. All you need is an
  41.          ANSI-compatible C or C++ compiler. The programs you create can be
  42.          run within ProBoard by executing a new menu function.
  43.  
  44.          The ProBoard SDK files included with ProBoard are free software,
  45.          so anyone who does not use ProBoard to run a BBS on a regular
  46.          basis, but wants to write extension files, is allowed to do so
  47.          without registering ProBoard. You can distribute any ProBoard
  48.          extension files (PEX files) royalty-free. As far as we are
  49.          concerned, any program you develop with the ProBoard SDK is your
  50.          property.
  51.  
  52.  
  53.  
  54.         ┌──────────────────────────────────────────────────────────────────┐
  55.         │ Requirements                                                     │
  56.         └──────────────────────────────────────────────────────────────────┘
  57.  
  58.          To create your own programs you need:
  59.  
  60.          - An ANSI compatible C or C++ compiler. Compilers known to be
  61.            compatible with the ProBoard SDK are:
  62.  
  63.               - Zortech C/C++ 2.0 - 3.0
  64.               - Microsoft C/C++ 5.1 - 7.0
  65.               - Borland C++ 2.0 - 4.5
  66.               - Turbo C++ 1.0
  67.               - Turbo C 1.0 - 2.0
  68.  
  69.            Other compilers may work too, but were not tested.
  70.  
  71.          - An MS-compatible linker (usually the one that came with your
  72.            compiler).
  73.  
  74.            Linkers known to work with the ProBoard SDK are:
  75.  
  76.               - All Microsoft Linkers (LINK.EXE)
  77.               - Borland's Turbo Link (TLINK)
  78.               - Zortech's BLINK
  79.  
  80.          - The ProBoard SDK include file PB_SDK.H
  81.  
  82.          - The ProBoard SDK library PB_SDK.LIB (for non-Borland compilers)
  83.          - The ProBoard SDK file PB_SDK.OBJ (for Borland 3.x compilers)
  84.  
  85.  
  86.                                       - 1 -
  87.  
  88.  
  89.  
  90.         ┌──────────────────────────────────────────────────────────────────┐
  91.         │ Creating ProBoard Executables (PEX-files)                        │
  92.         └──────────────────────────────────────────────────────────────────┘
  93.  
  94.          To create your own ProBoard executable (.PEX file), you first
  95.          create a source file, say MYPROG.C. When ProBoard loads a PEX
  96.          file, it executes the function main() in your program. This
  97.          function is defined as:
  98.  
  99.          void
  100.          main(int argc,char *argv[])
  101.          {
  102.           ...
  103.          }
  104.  
  105.          The parameters 'argc' & 'argv' contain optional data that can be
  106.          given to your program at load time (exactly like C's argc and argv
  107.          parameters).  Creating this main() function is the only thing you
  108.          need to do to write a valid ProBoard executable. From this point
  109.          on, it's just like writing a regular C program.  Most of the ANSI
  110.          standard library functions are available, plus many ProBoard-
  111.          specific functions and global variables, used for interfacing
  112.          between your program and the ProBoard environment.  As in a regular
  113.          executable, you can build your program from several source files.
  114.  
  115.          This is a tiny sample ProBoard program:
  116.  
  117.          #include "pb_sdk.h"
  118.  
  119.          void
  120.          main()
  121.          {
  122.           printf("You have %d minutes left.\n",TimeLeft());
  123.  
  124.           AddTime(10);
  125.  
  126.           printf("Now you have %d minutes left.\n",TimeLeft());
  127.          }
  128.  
  129.  
  130.          Included with ProBoard are a few example programs (in source form
  131.          of course).
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142.                                       - 2 -
  143.  
  144.  
  145.  
  146.         ┌──────────────────────────────────────────────────────────────────┐
  147.         │ Compiling and Linking                                            │
  148.         └──────────────────────────────────────────────────────────────────┘
  149.  
  150.          ProBoard executables have to be compiled using the LARGE memory
  151.          model.
  152.  
  153.          For example (Turbo C++) : tcc -c -ml myprog.c
  154.  
  155.          Once you have your .OBJ file (in this case MYPROG.OBJ), you have
  156.          to link it with the ProBoard SDK library (PB_SDK.LIB). You have to
  157.          specify a filename as output filename. The linked executable must
  158.          have extension .PEX. It is important to disable linking of the
  159.          default compiler libraries!! It is also required to turn on
  160.          case sensitivity.
  161.  
  162.          e.g.   Turbo C++ :  TLINK MYPROG,MYPROG.PEX,,PB_SDK /N /C
  163.                 Microsoft :  LINK MYPROG,MYPROG.PEX,,PB_SDK /NOD /NOI;
  164.                 Zortech   :  BLINK MYPROG,MYPROG.PEX,,PB_SDK /NOD /NOI;
  165.  
  166.          That's all there is to it. Now you can run your program through
  167.          ProBoard's menu function 60.
  168.  
  169.          I will now give the compiler syntax for some popular compilers:
  170.  
  171.           Zortech C/C++ : ztc -c -a -ml myprog.c
  172.           Microsoft C   : cl -Zep -Gs -c -AL myprog.c
  173.           Turbo C/C++   : tcc -c -ml myprog.c
  174.           Borland C++   : bcc -c -ml myprog.c
  175.  
  176.          And linker syntax:
  177.  
  178.           Borland       : TLINK PB_SDK MYPROG,MYPROG.PEX /N /C
  179.           Microsoft     : LINK MYPROG,MYPROG.PEX,,PB_SDK /NOD /NOI;
  180.           Zortech       : BLINK MYPROG,MYPROG.PEX,,PB_SDK /NOD /NOI;
  181.  
  182.          Note that the syntax for Borland C++ has changed from the previous
  183.          versions of the SDK. It is required that you specify PB_SDK.OBJ
  184.          BEFORE your object files, and don't link PB_SDK.LIB.
  185.  
  186.  
  187.  
  188.         ┌──────────────────────────────────────────────────────────────────┐
  189.         │ Restrictions                                                     │
  190.         └──────────────────────────────────────────────────────────────────┘
  191.  
  192.          There are few restrictions in writing ProBoard executables. For C
  193.          programs there are actually only two major restriction: long math
  194.          & floating point operations.
  195.  
  196.  
  197.  
  198.                                       - 3 -
  199.  
  200.  
  201.  
  202.          Due to the fact that all compilers generate function calls to
  203.          multiply, divide and shift long integers, and that every compiler
  204.          vendor uses its own array of functions, it is impossible to
  205.          include these functions in the ProBoard SDK. As a result, it is
  206.          not directly possible to perform these operations on long values
  207.          (eg. long1 = long2 * long3). However, we did include functions to
  208.          perform these operations, but you will have to call these
  209.          functions explicitly (eg. long1 = l_mul(long2,long3)).  People who
  210.          know their compiler well, can work around this problem by
  211.          extracting the long math functions from the standard library, and
  212.          linking them with the PEX file. For example, the long math
  213.          functions used by the Zortech compiler are in the module
  214.          LMATH.OBJ, located in the library ZLC.LIB. Extracting this module
  215.          is as simple as :  ZORLIB ZLS *LMATH;
  216.  
  217.          These are the ProBoard long math functions that you can use:
  218.  
  219.          long l_mul(long1,long2)   Multiply 2 long values   = long1 * long2
  220.          long l_div(long1,long2)   Divide 2 long values     = long1 / long2
  221.          long l_mod(long1,long2)   Modulo of 2 long values  = long1 % long2
  222.          long l_shl(long1,int1)    Left shift a long value  = long1 << int1
  223.          long l_shr(long1,int1)    Right shift a long value = long1 >> int1
  224.  
  225.          The functions l_div(), l_mod(), l_shl() and l_shr() are also
  226.          available for unsigned long values: ul_div(), ul_mod(), ul_shl()
  227.          and ul_shr().
  228.  
  229.          Floating point operations are NOT supported. So it is not possible
  230.          to use 'double' and 'float' variables & constants.
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.                                       - 4 -
  255.  
  256.  
  257.  
  258.          Another major restriction only affects C++ programs that are
  259.          compiled with some other compiler than Borland C/C++ 3.x or
  260.          Zortech C++ 3.0.  In a ProBoard C++ program that is not compiled
  261.          with one of the compilers mentioned, you can't declare global
  262.          variables that have constructors or destructors (ie. no static
  263.          constructors & destructors). So this will compile fine, but will
  264.          certainly crash your machine:
  265.  
  266.          class myclass
  267.             {
  268.                 int a;
  269.             public:
  270.                 x() { .... some action .... }
  271.                ~x() { .... some action .... }
  272.             };
  273.  
  274.          myclass some_global_object;
  275.  
  276.          main()
  277.          {
  278.          ...
  279.          }
  280.  
  281.          You can, however, use objects with constructors and destructors,
  282.          as long as they are declared within a function. So this would
  283.          work:
  284.  
  285.          main()
  286.          {
  287.           myclass some_local_object;
  288.           ....
  289.          }
  290.  
  291.  
  292.  
  293.         ┌──────────────────────────────────────────────────────────────────┐
  294.         │ Library functions supported                                      │
  295.         └──────────────────────────────────────────────────────────────────┘
  296.  
  297.          Almost all standard library functions are supported. Note that all
  298.          functions that write to the standard output device (printf,
  299.          putchar,...) write their output to the ProBoard window and to the
  300.          user (through the modem).  Functions that read from the standard
  301.          input device and from the keyboard are NOT supported.
  302.          (scanf,getch,gets,...) We provide substitutes for these functions.
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.                                       - 5 -
  311.  
  312.  
  313.  
  314.          Functions supported:
  315.  
  316.               fopen , freopen , fseek , ftell , fgets , fgetc , fflush
  317.               fclose , fputs , getc , getchar , gets , fputc , putc ,
  318.               putchar , puts , fread , fwrite , printf , fprintf ,
  319.               vfprintf , vprintf , sprintf , vsprintf , setbuf ,
  320.               setvbuf , remove , rename , rewind , clearerr , feof ,
  321.               isalpha , iscntrl , isdigit , isgraph , islower ,
  322.               isprint , ispunct , isspace , isupper , isxdigit ,
  323.               toupper , tolower , int86x , intdos , intdosx ,
  324.               dos_findfirst , dos_findnext , write , open , creat ,
  325.               close , unlink , chsize , dup , dup2 , lseek , access ,
  326.               filesize , filelength , isatty , atoi , atol , strtol ,
  327.               rand , srand , calloc , free , malloc , realloc , putenv
  328.               getenv , abs , labs , memcpy , memmove , strcpy , strncpy ,
  329.               strcat , strncat , memcmp , strcmp , strncmp , memchr ,
  330.               strchr , strcspn , strpbrk , strrchr , strspn , strstr ,
  331.               strtok , memset , strlen , memicmp , stpcpy , strcmpl ,
  332.               strnicmp , strdup , strlwr , strupr , strnset , strrev ,
  333.               strset , swab , strncmpl , strnicmp , clock , time , mktime ,
  334.               asctime , ctime , localtime , gmtime , strftime , sleep ,
  335.               usleep , msleep , difftime, mkdir(), chdir(), rmdir()
  336.  
  337.  
  338.          For information on these functions, consult your compiler's
  339.          library reference manual.
  340.  
  341.          In the string output functions (printf and puts), you can use the
  342.          following control codes in your string:
  343.  
  344.          \001 or \x01   Set output color to red
  345.          ::::    ::::
  346.          ::::    ::::
  347.          \007 or \x07   Set output color to white
  348.  
  349.          \x11 to \x17   Same as \1 to \7, but blinking colors
  350.  
  351.          \t             Stops output of string until user presses [Enter]
  352.          \f             Clears the user's screen (if enabled in the user's
  353.                         record)
  354.  
  355.  
  356.          NOTE: Do NOT include any standard include files from your
  357.          compiler. The only include file you can use is PB_SDK.H.
  358.          THAT'S IT!!
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  
  366.                                       - 6 -
  367.  
  368.  
  369.  
  370.         ┌──────────────────────────────────────────────────────────────────┐
  371.         │ ProBoard Interface Functions                                     │
  372.         └──────────────────────────────────────────────────────────────────┘
  373.  
  374.          This is a list of all the functions that can be used to interface
  375.          with ProBoard.
  376.  
  377.          Several types have been defined in the file PB_SDK.H
  378.  
  379.            bool    : a boolean value that can have the values TRUE or FALSE
  380.            byte    : an unsigned character (8 bits)
  381.            word    : an unsigned short integer (16 bits)
  382.            dowrd   : an unsigned long integer (32 bits)
  383.            KEY     : used for key scan codes (for sysopkey handlers and the
  384.                      ScanKey() function).
  385.  
  386.  
  387.          ──────────────────────────────────────────────────────────────────
  388.          void AddTime(int min);
  389.          ──────────────────────────────────────────────────────────────────
  390.  
  391.          Adds 'min' minutes to the user's time left. If 'min' is negative,
  392.          the number of minutes will be subtracted from the time left.
  393.  
  394.          Examples:    AddTime(10);         /* Adds 10 minutes */
  395.                       AddTime(-5);         /* Subtracts 5 minutes */
  396.  
  397.  
  398.  
  399.          ──────────────────────────────────────────────────────────────────
  400.          int TimeLeft(void);
  401.          ──────────────────────────────────────────────────────────────────
  402.  
  403.          Returns the time left in minutes for the current user.
  404.  
  405.  
  406.  
  407.          ──────────────────────────────────────────────────────────────────
  408.          int TimeOnline(void);
  409.          ──────────────────────────────────────────────────────────────────
  410.  
  411.          Returns the time in minutes that the current user is online.
  412.  
  413.  
  414.  
  415.  
  416.  
  417.  
  418.  
  419.  
  420.  
  421.  
  422.                                       - 7 -
  423.  
  424.  
  425.  
  426.          ──────────────────────────────────────────────────────────────────
  427.          void SuspendTimer(void);
  428.          ──────────────────────────────────────────────────────────────────
  429.  
  430.          Suspends the online-timer for the current user. No time will be
  431.          subtracted until RestartTimer() is called.
  432.  
  433.  
  434.  
  435.          ──────────────────────────────────────────────────────────────────
  436.          void RestartTimer(void);
  437.          ──────────────────────────────────────────────────────────────────
  438.  
  439.          Restarts the timer after a call to SuspendTimer().
  440.  
  441.  
  442.  
  443.          ──────────────────────────────────────────────────────────────────
  444.          void AdjustTime(void);
  445.          ──────────────────────────────────────────────────────────────────
  446.  
  447.          Call this function if you changed the user's level. This
  448.          recalculates all limits (time,download,...).
  449.  
  450.  
  451.  
  452.          ──────────────────────────────────────────────────────────────────
  453.          void MsgEd(void);
  454.          ──────────────────────────────────────────────────────────────────
  455.  
  456.          Fires up the internal message editor or the fullscreen editor,
  457.          depending on the settings of the user. The message will be stored
  458.          in the file MSGTMP in the current directory. If a message is
  459.          aborted, the file MSGTMP will be deleted by the message editor.
  460.          If you create a MSGTMP file before invoking the message editor,
  461.          this file will be used as a 'quote' message.
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.                                       - 8 -
  479.  
  480.  
  481.  
  482.          ──────────────────────────────────────────────────────────────────
  483.          int PostMessage(char *from,char *to,char *subject,int area,
  484.                          bool pvt);
  485.          ──────────────────────────────────────────────────────────────────
  486.  
  487.          Posts a message to a user.
  488.  
  489.             from    = Name of the sender
  490.             to      = Name of the user you're sending the message to
  491.             subject = Subject of the message
  492.             area    = Message area number where the message has to
  493.                       be posted in.
  494.             pvt     = Private status (TRUE=private, FALSE=public)
  495.  
  496.          No checking is performed on any of the parameters!
  497.  
  498.  
  499.          Return value: -1 on error
  500.                         0 if ok
  501.  
  502.  
  503.  
  504.          ──────────────────────────────────────────────────────────────────
  505.          int PostNetmail(char *from,char *to,char *subject,int area,
  506.                          FIDO_NODE *address,bool attach,bool crash,
  507.                          bool kill);
  508.          ──────────────────────────────────────────────────────────────────
  509.  
  510.          Posts a netmail message.
  511.  
  512.             from    = Name of the sender
  513.             to      = Name of the user you're sending the message to
  514.             subject = Subject of the message
  515.             area    = Message area number where the message has to
  516.                       be posted in
  517.             address = Destination node number of this message.
  518.             attach  = TRUE for a file attach message
  519.             crash   = TRUE if this message is a crashmail message
  520.             kill    = TRUE if the message has to be deleted after it is
  521.                       sent
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.                                       - 9 -
  535.  
  536.  
  537.  
  538.          FIDO_NODE is a structure with the following fields:
  539.  
  540.            struct
  541.              {
  542.               unsigned zone;  /* Zone number  */
  543.               unsigned net;   /* Net number   */
  544.               unsigned node;  /* Node number  */
  545.               unsigned point; /* Point number */
  546.              }
  547.  
  548.          No checking is performed on any of the parameters!
  549.  
  550.          Return value: -1 on error
  551.                         0 if ok
  552.  
  553.  
  554.  
  555.          ──────────────────────────────────────────────────────────────────
  556.          bool ReadMsgArea(int area,MSGAREA *ma);
  557.          ──────────────────────────────────────────────────────────────────
  558.  
  559.          Reads data about a message area.
  560.  
  561.               area  = Message area number (1-200)
  562.               ma    = Pointer to a MSGAREA structure to be filled
  563.  
  564.          Check the file PB_SDK.H for details about the MSGAREA structure
  565.          definition.
  566.  
  567.          Return value:  FALSE if not defined
  568.                         TRUE  if read ok
  569.  
  570.  
  571.  
  572.          ──────────────────────────────────────────────────────────────────
  573.          bool ReadMessage(MESSAGE *msg,long msgid,int areanum);
  574.          ──────────────────────────────────────────────────────────────────
  575.  
  576.          Reads message id <msgid> from area numer <areanum> into the
  577.          MESSAGE structure.  To access the text of the message, use the
  578.          function CreateMessageText().  See the file PB_SDK.H for a
  579.          description of the MESSAGE structure.
  580.  
  581.          Return value: FALSE if the message does not exists
  582.                        TRUE  if the message is read ok
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590.                                       - 10 -
  591.  
  592.  
  593.  
  594.          ──────────────────────────────────────────────────────────────────
  595.          void WriteMSGTMP(char *text);
  596.          ──────────────────────────────────────────────────────────────────
  597.  
  598.          Writes the string <text> to the file MSGTMP. The file is always
  599.          recreated when using this function. To append text to MSGTMP,
  600.          use the function AppendMSGTMP(). You have to insert your own CR/LF
  601.          pairs in the text if you want to force a newline.  Lines can be
  602.          longer than 80 characters.  The message processing functions will
  603.          do a word-wrap if necessary.  Do NOT insert a single CR or LF in
  604.          the text. (\r or \n).
  605.  
  606.  
  607.  
  608.          ──────────────────────────────────────────────────────────────────
  609.          void AppendMSGTMP(char *text);
  610.          ──────────────────────────────────────────────────────────────────
  611.  
  612.          Same as WriteMSGTMP(), but adds text to an EXISTING file.
  613.  
  614.  
  615.  
  616.          ──────────────────────────────────────────────────────────────────
  617.          void ShowMessage(MESSAGE *msg);
  618.          ──────────────────────────────────────────────────────────────────
  619.  
  620.          Shows the message <msg> to the user, including header and message
  621.          text.
  622.          See the file PB_SDK.H for an description of the MESSAGE structure.
  623.  
  624.  
  625.  
  626.          ──────────────────────────────────────────────────────────────────
  627.          void CreateMessageText(MESSAGE *msg);
  628.          ──────────────────────────────────────────────────────────────────
  629.  
  630.          Reads the text that belongs to message <msg>, and stores it in a
  631.          file called MSGTMP in the current directory. This file can then be
  632.          accessed as an ordinary textfile.
  633.  
  634.  
  635.  
  636.          ──────────────────────────────────────────────────────────────────
  637.          void CreateMessageTextString(MESSAGE *msg,char *text,int max);
  638.          ──────────────────────────────────────────────────────────────────
  639.  
  640.          Reads the text that belongs to message <msg>, and stores it in the
  641.          string <text>. The text will be terminated by a '\0' character.
  642.          You have to specify a maximum number of characters that can be
  643.          stored in <text>.
  644.  
  645.  
  646.                                       - 11 -
  647.  
  648.  
  649.  
  650.          ──────────────────────────────────────────────────────────────────
  651.          bool FirstMessage(MESSAGE *msg,int area,int order,long first);
  652.          bool NextMessage(MESSAGE *msg,int area,int order);
  653.          ──────────────────────────────────────────────────────────────────
  654.  
  655.          These functions are used to read messages in forward or reverse
  656.          order. To start scanning messages, you have to call the
  657.          FirstMessage() function first, and the NextMessage() function to
  658.          read more messages.
  659.  
  660.          msg   = MESSAGE structure where the message has to be stored.
  661.          area  = area number to read messages in
  662.          order = 1 for forward order, -1 for reverse order
  663.          first = message to start reading from. This message does NOT
  664.                  need to exist. The first non-deleted message following
  665.                  this message will be read first.
  666.  
  667.          See the file PB_SDK.H for an description of the MESSAGE structure.
  668.  
  669.          Return value: FALSE  No more messages found.
  670.                        TRUE   Message was found and read ok.
  671.  
  672.  
  673.          This is an example on how to use these functions:
  674.  
  675.          result = FirstMessage(msg,5,+1,1);
  676.          while(result == TRUE)
  677.            {
  678.             /* Do something with the message */
  679.             result = NextMessage(msg,5,+1);
  680.            }
  681.  
  682.  
  683.  
  684.          ──────────────────────────────────────────────────────────────────
  685.          void DeleteMessage(MESSAGE *msg);
  686.          ──────────────────────────────────────────────────────────────────
  687.  
  688.          Deletes message <msg>.
  689.  
  690.  
  691.  
  692.          ──────────────────────────────────────────────────────────────────
  693.          void MarkMessage(long msgid);
  694.          ──────────────────────────────────────────────────────────────────
  695.  
  696.          Marks message <msgid> for later retrieval. Up to 200 messages can
  697.          be marked.
  698.  
  699.  
  700.  
  701.  
  702.                                       - 12 -
  703.  
  704.  
  705.  
  706.          ──────────────────────────────────────────────────────────────────
  707.          void ReadMarkedMessages(void);
  708.          ──────────────────────────────────────────────────────────────────
  709.  
  710.          Shows all marked messages to the user, with the option to wait
  711.          after each message. If the user selected to wait after each
  712.          message, the standard message options menu will be shown to the
  713.          user. (Next,Prev,Stop,...).
  714.          In fact, this function is identical to menu function "Read
  715.          Messages", with the user selecting "Marked".
  716.  
  717.  
  718.  
  719.          ──────────────────────────────────────────────────────────────────
  720.          void ListMarkedMessages(void);
  721.          ──────────────────────────────────────────────────────────────────
  722.  
  723.          Is similar to ReadMarkedMessages(), but this function acts as a
  724.          "QuickScan Messages" with the user selecting "Marked".
  725.  
  726.  
  727.  
  728.          ──────────────────────────────────────────────────────────────────
  729.          void UnMarkAllMessages(void);
  730.          ──────────────────────────────────────────────────────────────────
  731.  
  732.          Unmarks all messages that were previously marked. You have to call
  733.          this function before marking any messages, because the list of
  734.          marked messages is remembered until a user logs off.
  735.  
  736.  
  737.  
  738.          ──────────────────────────────────────────────────────────────────
  739.          int NumMsgAreas(void);
  740.          ──────────────────────────────────────────────────────────────────
  741.  
  742.          Returns the highest message area number that is not empty.
  743.  
  744.  
  745.  
  746.          ──────────────────────────────────────────────────────────────────
  747.          long GetLastRead(int areanum , long user_recno);
  748.          void SetLastRead(int areanum , long user_recno , long msgid);
  749.          ──────────────────────────────────────────────────────────────────
  750.  
  751.          Reads / Sets the lastread pointer for a specific user and message
  752.          area.  If GetLastRead() returns -1, an error occurred.
  753.  
  754.  
  755.  
  756.  
  757.  
  758.                                       - 13 -
  759.  
  760.  
  761.  
  762.          <areanum> ..... The area number (1-10000)
  763.          <user_recno> .. The record number of the user (0 - ...)
  764.          <msgid> ....... The id of the message you want to set the
  765.                          lastread pointer to.
  766.  
  767.  
  768.  
  769.          ──────────────────────────────────────────────────────────────────
  770.          int FuzzySearch(char *text,char *string,int degree);
  771.          ──────────────────────────────────────────────────────────────────
  772.  
  773.          Performs a fuzzy search for <string> in <text>. <degree> is the
  774.          percentage of the characters in <string> that have to match.
  775.  
  776.          Return value: -1 if not found
  777.                        >0 percentage of characters matched
  778.  
  779.  
  780.  
  781.          ──────────────────────────────────────────────────────────────────
  782.          IO_... functions
  783.          ──────────────────────────────────────────────────────────────────
  784.  
  785.          All functions starting with IO_ are low-level functions to access
  786.          the serial port directly. Do NOT use these functions for ordinary
  787.          I/O operations. They are intended for writing file transfer
  788.          protocols. See the file PB_SDK.H for the prototypes of these
  789.          functions.
  790.  
  791.  
  792.  
  793.          ──────────────────────────────────────────────────────────────────
  794.          char WaitKey(void);
  795.          ──────────────────────────────────────────────────────────────────
  796.  
  797.          Waits for a character to be read from the modem or local keyboard.
  798.  
  799.          Return value: the character read.
  800.  
  801.  
  802.  
  803.  
  804.  
  805.  
  806.  
  807.  
  808.  
  809.  
  810.  
  811.  
  812.  
  813.  
  814.                                       - 14 -
  815.  
  816.  
  817.  
  818.          ──────────────────────────────────────────────────────────────────
  819.          char WaitKeys(char *keylist);
  820.          ──────────────────────────────────────────────────────────────────
  821.  
  822.          Waits for any character specified in <keylist>.
  823.  
  824.          Return value: the key from the list that was pressed (converted to
  825.                        uppercase if the key is a letter).
  826.  
  827.          Example : c = WaitKeys("ABC\r\x1b");
  828.                    /* Waits for A,B,C,<Enter> or <Esc> */
  829.  
  830.  
  831.  
  832.          ──────────────────────────────────────────────────────────────────
  833.          void Input(char *buf,int len,int readmode);
  834.          ──────────────────────────────────────────────────────────────────
  835.  
  836.          Asks for a string from the user. The string is stored in <buf>,
  837.          and the user will not be allowed to enter more than <len>
  838.          characters.
  839.  
  840.          <readmode> :  INPUT_ALL      : All characters are allowed
  841.                        INPUT_UPFIRST  : First character of each word is
  842.                                         converted to uppercase.
  843.                        INPUT_UPALL    : All characters are converted to
  844.                                         uppercase.
  845.                        INPUT_DIGITS   : Only digits are accepted.
  846.  
  847.                        INPUT_NOFIELD  : OR together with any of the
  848.                                         previous modes if you don't want an
  849.                                         input-field background to be
  850.                                         displayed.
  851.  
  852.  
  853.  
  854.          ──────────────────────────────────────────────────────────────────
  855.          bool Ask(bool default);
  856.          ──────────────────────────────────────────────────────────────────
  857.  
  858.          Asks for a Yes or No response from the user. Pressing 'Y' returns
  859.          TRUE and outputs "Yes". Pressing 'N' returns FALSE and sends "No"
  860.          to the user. Pressing <Enter> returns <default>, and sends "Yes"
  861.          or "No", depending on <default>.
  862.  
  863.  
  864.  
  865.  
  866.  
  867.  
  868.  
  869.  
  870.                                       - 15 -
  871.  
  872.  
  873.  
  874.          ──────────────────────────────────────────────────────────────────
  875.          char PeekChar(void);
  876.          ──────────────────────────────────────────────────────────────────
  877.  
  878.          Checks if a character is available in the input buffer, and
  879.          returns that character if there is.
  880.  
  881.          Return value:     0 if no character available
  882.                         != 0 the character read (key pressed by user)
  883.  
  884.  
  885.  
  886.          ──────────────────────────────────────────────────────────────────
  887.          void SetColor(char color);
  888.          ──────────────────────────────────────────────────────────────────
  889.  
  890.          Changes the current output color. All text that is output after
  891.          this function is called will be displayed in the specified color.
  892.          This function does nothing when the user does not have ANSI or
  893.          AVATAR enabled.
  894.  
  895.          <color> can be one of the following:
  896.  
  897.             BLACK , RED , GREEN , YELLOW , MAGENTA , BLUE , CYAN , WHITE
  898.  
  899.  
  900.  
  901.          ──────────────────────────────────────────────────────────────────
  902.          void SetfullColor(unsigned char color);
  903.          ──────────────────────────────────────────────────────────────────
  904.  
  905.          Changes the current foreground & background color. The color code
  906.          is an IBM-type screen color code. This function does nothing when
  907.          the user does not have ANSI or AVATAR enabled.
  908.  
  909.          Some examples:
  910.  
  911.              0x1E : Bright yellow on dark blue background.
  912.              0x87 : Blinking white on a black background.
  913.  
  914.  
  915.  
  916.          ──────────────────────────────────────────────────────────────────
  917.          void GotoXY(int x,int y);
  918.          ──────────────────────────────────────────────────────────────────
  919.  
  920.          Moves the cursor to position (x,y). The upper left corner of the
  921.          screen is (1,1). This function does nothing when the user does
  922.          not have ANSI or AVATAR enabled.
  923.  
  924.  
  925.  
  926.                                       - 16 -
  927.  
  928.  
  929.  
  930.          ──────────────────────────────────────────────────────────────────
  931.          void ClrEol();
  932.          ──────────────────────────────────────────────────────────────────
  933.  
  934.          Clears from the current cursor position to the end of the
  935.          line. This function does nothing when the user does not have ANSI
  936.          or AVATAR enabled.
  937.  
  938.  
  939.  
  940.          ──────────────────────────────────────────────────────────────────
  941.          void EnableStop(void);
  942.          void DisableStop(void);
  943.          bool Stopped(void);
  944.          ──────────────────────────────────────────────────────────────────
  945.  
  946.          Enables stopping of output by pressing 'S'. When enabled, a user
  947.          can press 'S' to stop incoming text. When this happens, any
  948.          string output function will immediately return to the caller, en
  949.          the function Stopped() will return TRUE to indicate that the user
  950.          requested to stop output.
  951.  
  952.          EnableStop()       Enables this feature and sets the "stopped"
  953.                             status to FALSE .
  954.          DisableStop()      Disables the stop feature.
  955.          Stopped()          Returns the "stopped" flag (TRUE or FALSE).
  956.  
  957.  
  958.          Example:
  959.  
  960.               EnableStop();
  961.               for(i=0;i<100;i++)
  962.                 {
  963.                  printf("...something...");
  964.                  if(Stopped()) break;
  965.                 }
  966.  
  967.  
  968.  
  969.  
  970.  
  971.  
  972.  
  973.  
  974.  
  975.  
  976.  
  977.  
  978.  
  979.  
  980.  
  981.  
  982.                                       - 17 -
  983.  
  984.  
  985.  
  986.          ──────────────────────────────────────────────────────────────────
  987.          char ShowHotkeyFile(char *filename,char *hotkeys);
  988.          ──────────────────────────────────────────────────────────────────
  989.  
  990.          Shows the file <filename> to the user, and watches for incoming
  991.          keys that are specified in <hotkeys>. If one of these keys is
  992.          detected, the function stops output, and returns the hotkey. The
  993.          "stop" feature will be enabled when sending the file.
  994.  
  995.          Return value:    0 : File sent completely and no hotkeys pressed.
  996.                           1 : 'S' pressed (output stopped)
  997.                           2 : File not found
  998.                         !=2 : Hotkey detected
  999.  
  1000.  
  1001.  
  1002.          ──────────────────────────────────────────────────────────────────
  1003.          char ShowHotkeyANSIFile(char *filename,char *hotkeys);
  1004.          ──────────────────────────────────────────────────────────────────
  1005.  
  1006.          This function is identical to ShowKotkeyFile(), except for the
  1007.          fact that no extension and path can be specified. Depending on the
  1008.          setting of the user, <filename>.ANS/ASC in the textfiles
  1009.          directory will be sent. If no .ANS file is found, it will try to
  1010.          send the .ASC file. If that fails too, 2 will be returned.
  1011.  
  1012.          Return value:    0 : File sent completely and no hotkeys pressed.
  1013.                           1 : 'S' pressed (output stopped)
  1014.                           2 : File not found
  1015.                         !=2 : Hotkey detected
  1016.  
  1017.  
  1018.  
  1019.          ──────────────────────────────────────────────────────────────────
  1020.          void InitLineCounter(void);
  1021.          bool LineCounter(void);
  1022.          ──────────────────────────────────────────────────────────────────
  1023.  
  1024.          These functions are used to support page pausing ("More Y/N").
  1025.          Calling InitLineCounter() initializes the line counter to 0.
  1026.          Every time you call LineCounter(), the line counter is incremented
  1027.          by one. If the counter reaches the screen length, the user will be
  1028.          asked if he wants to continue reading. If he selects "No", the
  1029.          LineCounter() function will return FALSE.
  1030.  
  1031.  
  1032.  
  1033.  
  1034.  
  1035.  
  1036.  
  1037.  
  1038.                                       - 18 -
  1039.  
  1040.  
  1041.  
  1042.          Example:
  1043.  
  1044.              InitLineCounter();
  1045.              for(;;)
  1046.                {
  1047.                 printf("...something...\n");
  1048.                 if(!LineCounter()) break;
  1049.                }
  1050.  
  1051.  
  1052.  
  1053.          ──────────────────────────────────────────────────────────────────
  1054.          bool ExternalInput(void);
  1055.          ──────────────────────────────────────────────────────────────────
  1056.  
  1057.          Returns TRUE when the last character that was read through any of
  1058.          the input routings originated from the remote keyboard (ie. the
  1059.          sysop did not type it).
  1060.  
  1061.  
  1062.  
  1063.          ──────────────────────────────────────────────────────────────────
  1064.          int ReadUser(USER_REC *rec,int recnr);
  1065.          ──────────────────────────────────────────────────────────────────
  1066.  
  1067.          Reads user record number <recnr> (0-...) from the user file and
  1068.          stores it in <rec>.
  1069.  
  1070.          Return value:  -1 if record does not exist.
  1071.                          0 if record is read ok.
  1072.  
  1073.  
  1074.  
  1075.          ──────────────────────────────────────────────────────────────────
  1076.          void WriteUser(USER_REC *rec);
  1077.          ──────────────────────────────────────────────────────────────────
  1078.  
  1079.          Writes user record <rec> to the user file.  The record number is
  1080.          stored in the USER_REC structure.  If you want to write a
  1081.          user record to a different position in the user file, you have to
  1082.          change the 'record' field in the USER_REC structure.
  1083.  
  1084.  
  1085.  
  1086.  
  1087.  
  1088.  
  1089.  
  1090.  
  1091.  
  1092.  
  1093.  
  1094.                                       - 19 -
  1095.  
  1096.  
  1097.  
  1098.          ──────────────────────────────────────────────────────────────────
  1099.          bool SetUser(long recnr);
  1100.          ──────────────────────────────────────────────────────────────────
  1101.  
  1102.          Sets the internal ProBoard user record to record number <recnr>.
  1103.          This function should ONLY be called from _LOGIN.PEX !!
  1104.  
  1105.          Return value:  TRUE on success
  1106.                         FALSE on error
  1107.  
  1108.  
  1109.  
  1110.          ──────────────────────────────────────────────────────────────────
  1111.          char PlayMusic(char *filename,char *hotkeys);
  1112.          ──────────────────────────────────────────────────────────────────
  1113.  
  1114.          Plays a .MUS file. The file has to be located in the ProBoard
  1115.          system directory. Do not include a path and extension in
  1116.          <filename>. The music can be stopped if the sysop presses one of
  1117.          the keys specified in <hotkeys>.            ^^^^^
  1118.  
  1119.          Return value:   0   Music file played till the end
  1120.                          1   Music file not found
  1121.                          >1  The hotkey pressed by the SYSOP
  1122.                                                        ^^^^^
  1123.  
  1124.  
  1125.          ──────────────────────────────────────────────────────────────────
  1126.          void PostInfo(char *filename);
  1127.          ──────────────────────────────────────────────────────────────────
  1128.  
  1129.          Does exactly the same as the POSTINFO statement in a .Q-A file.
  1130.          No path and extension is allowed in <filename>. The file where
  1131.          the information will be written to will have the extension .ASW
  1132.          and will be placed in the ProBoard system directory.
  1133.  
  1134.  
  1135.  
  1136.          ──────────────────────────────────────────────────────────────────
  1137.          int ReadFileArea(int areanum,FILEAREA *fa);
  1138.          ──────────────────────────────────────────────────────────────────
  1139.  
  1140.          Reads information about file area number <areanum> in the <fa>
  1141.          structure.
  1142.          Check the file PB_SDK.H for details about the FILEAREA structure.
  1143.  
  1144.          Return value:   -1   File area does not exist
  1145.                           0   Ok
  1146.  
  1147.  
  1148.  
  1149.  
  1150.                                       - 20 -
  1151.  
  1152.  
  1153.  
  1154.          ──────────────────────────────────────────────────────────────────
  1155.          void MenuFunction(int function,char *data);
  1156.          ──────────────────────────────────────────────────────────────────
  1157.  
  1158.          Executes menu function <function> with <data>. For details, see
  1159.          the menu functions description in this file.
  1160.          There are named constants declared for each function in the file
  1161.          PB_SDK.H. It is recommended that you use these constants instead
  1162.          of numbers.
  1163.  
  1164.  
  1165.  
  1166.          ──────────────────────────────────────────────────────────────────
  1167.          void Log(int loglevel,char *fmt,...);
  1168.          ──────────────────────────────────────────────────────────────────
  1169.  
  1170.          With this function you can write information to the ProBoard
  1171.          logfile. The log entry will be written if the user has a loglevel
  1172.          that is greater than <loglevel> .
  1173.  
  1174.          <loglevel> can be one of the following:
  1175.  
  1176.              LOG_FRIEND , LOG_NORMAL , LOG_SUSPICIOUS , LOG_DANGEROUS
  1177.  
  1178.          If you want a log entry to be written regardless of the user's
  1179.          loglevel, use LOG_FRIEND.
  1180.  
  1181.          The Log() function works like the printf function: you can use
  1182.          format specifiers in the <fmt> string, and pass extra parameters.
  1183.  
  1184.          Example:   Log(LOG_NORMAL,"User's name = %s",CurUser->name);
  1185.  
  1186.  
  1187.  
  1188.          ──────────────────────────────────────────────────────────────────
  1189.          void HangUp();
  1190.          ──────────────────────────────────────────────────────────────────
  1191.  
  1192.          Hangs up the phone, logging off the user. It is exactly the same
  1193.          as pressing Alt-H.
  1194.  
  1195.  
  1196.  
  1197.          ──────────────────────────────────────────────────────────────────
  1198.          bool CheckAccess(int level,long flags);
  1199.          ──────────────────────────────────────────────────────────────────
  1200.  
  1201.          Checks if the current user can access something that requires
  1202.          <level> and <flags>. Returns TRUE if the user has access, FALSE if
  1203.          not.
  1204.  
  1205.  
  1206.                                       - 21 -
  1207.  
  1208.  
  1209.  
  1210.          ──────────────────────────────────────────────────────────────────
  1211.          KEY ScanKey(void);
  1212.          ──────────────────────────────────────────────────────────────────
  1213.  
  1214.          Checks the LOCAL keyboard for a key, and returns the scan code for
  1215.          that key. If no key is available, 0 will be returned.
  1216.  
  1217.          For a list of defined values for scan codes, check the file
  1218.          PB_SDK.H.
  1219.  
  1220.  
  1221.  
  1222.          ──────────────────────────────────────────────────────────────────
  1223.          bool GetFlag(long flags,char flagchar);
  1224.          void SetFlag(long flags,char flagchar);
  1225.          void ClearFlag(long flags,char flagchar);
  1226.          ──────────────────────────────────────────────────────────────────
  1227.  
  1228.          Access flags are stored in a long integer (32 bits). You have 3
  1229.          macros at your disposal to manipulate access flags:
  1230.  
  1231.             GetFlag   : Returns TRUE if flag <flagchar> is set
  1232.             SetFlag   : Turns flag <flagchar> on
  1233.             ClearFlag : Turns flag <flagchar> off
  1234.  
  1235.          <flagchar> must be a value from 1 to 32. 1-26 correspond to A-Z,
  1236.                     while 27-32 are the same as 1-6.
  1237.  
  1238.  
  1239.  
  1240.          ──────────────────────────────────────────────────────────────────
  1241.          int ErrorLevel(void);
  1242.          ──────────────────────────────────────────────────────────────────
  1243.  
  1244.          Returns the errorlevel of the last executed shell command (Through
  1245.          MenuFunction(MENU_SHELL,...))
  1246.  
  1247.  
  1248.  
  1249.          ──────────────────────────────────────────────────────────────────
  1250.          bool GetIniVar(char *fname,char *varname,char *value,int max);
  1251.          bool SetIniVar(char *fname,char *varname,char *value);
  1252.          ──────────────────────────────────────────────────────────────────
  1253.  
  1254.          These functions can be used to read and write to .INI files. These
  1255.          files are similar to the files used by MS Windows. They can be
  1256.          used to store settings for your application (PEX). An example
  1257.          of a .INI file:
  1258.  
  1259.  
  1260.  
  1261.  
  1262.                                       - 22 -
  1263.  
  1264.  
  1265.  
  1266.                DataPath = C:\PB\PEX\MYPEX\DATA
  1267.                ProgPath = C:\PB\PEX\MYPEX
  1268.                MaxUsers = 10
  1269.  
  1270.          This is a standard ASCII file, with each line in the form
  1271.             <varname> = <value>
  1272.  
  1273.          The value of a specific variable can be read by calling the
  1274.          function GetIniVar(). Setting a variable (writing to the .INI file
  1275.          or createing it if it doesn't exist yet) can be done by calling
  1276.          SetIniVar().
  1277.  
  1278.          The parameters for the functions are:
  1279.  
  1280.              <fname>      Name of the .INI file. The extension of the file
  1281.                           will always be changed to .INI by ProBoard.
  1282.              <varname>    Name of the variable (case INsensitive)
  1283.              <value>      For GetIniVar() : a pointer to a buffer where the
  1284.                                             variable's contents will be
  1285.                                             stored.
  1286.                           For SetIniVar() : a pointer to the value of the
  1287.                                             variable.
  1288.              <max>        Maximum number of characters that can be copied
  1289.                           in <value> (including trailing '\0')
  1290.  
  1291.  
  1292.          Return value: FALSE if the file could not be opened or the
  1293.                        variable does not exist.
  1294.  
  1295.  
  1296.  
  1297.          ──────────────────────────────────────────────────────────────────
  1298.          void exit(void);
  1299.          ──────────────────────────────────────────────────────────────────
  1300.  
  1301.          Exits the current pex-program, and unloads it from memory.
  1302.  
  1303.  
  1304.  
  1305.  
  1306.  
  1307.  
  1308.  
  1309.  
  1310.  
  1311.  
  1312.  
  1313.  
  1314.  
  1315.  
  1316.  
  1317.  
  1318.                                       - 23 -
  1319.  
  1320.  
  1321.  
  1322.          ──────────────────────────────────────────────────────────────────
  1323.          void ExitTSR(void);
  1324.          ──────────────────────────────────────────────────────────────────
  1325.  
  1326.          Exits the current pex-program, and leaves it resident. This has
  1327.          some important implications:
  1328.  
  1329.           - All global and static variables keep their values for
  1330.             subsequent executions.
  1331.           - When the same pex-file is run again through menu function 60,
  1332.             the resident copy will be executed. This will result in faster
  1333.             loading.
  1334.           - Any handlers that were installed will be called.
  1335.  
  1336.  
  1337.  
  1338.          ──────────────────────────────────────────────────────────────────
  1339.          void InstallHandler(int handler,function);
  1340.          ──────────────────────────────────────────────────────────────────
  1341.  
  1342.          This is probably the most advanced and complicated function in the
  1343.          ProBoard SDK. With this function you can set up a "handler" for a
  1344.          specific action. Right now, only two types of handlers are
  1345.          supported: a replacement for the sysopkey-handler and a handler
  1346.          to intercept loss of carrier. This way you can create your own
  1347.          sysopkeys, or change the behaviour of existing sysopkeys. You could
  1348.          create a handler that intercepts the Alt-J key, and write your own
  1349.          flavor. In future versions you will be able to set up handlers for
  1350.          low-level I/O operations. So you could replace all I/O routines by
  1351.          your own functions. This way you can support your own exotic
  1352.          hardware or something like that. Anything goes!
  1353.  
  1354.             handler   : Handler type. At this time, only HANDLER_SYSOPKEY
  1355.                         and HANDLER_HANGUP are supported.
  1356.             function  : A pointer to the handler function you created.
  1357.  
  1358.          You can install as many handlers as you want.  When the PEX is
  1359.          removed from memory (when the PEX exits), all handlers that were
  1360.          installed will be removed by ProBoard.
  1361.  
  1362.          The handler function is a function that returns an integer. The
  1363.          parameters depend on the type of handler you are creating.
  1364.  
  1365.  
  1366.  
  1367.  
  1368.  
  1369.  
  1370.  
  1371.  
  1372.  
  1373.  
  1374.                                       - 24 -
  1375.  
  1376.  
  1377.  
  1378.          For HANDLER_SYSOPKEY the handler function has to be declared like
  1379.          this:
  1380.  
  1381.          int sysopkeyhandler(KEY k)
  1382.          {
  1383.          ...
  1384.          }
  1385.  
  1386.          A sysopkey handler intercepts any special key that is pressed by the
  1387.          sysop. (like F1,Alt-H,...). You can redefine any key, or add your
  1388.          own.
  1389.  
  1390.  
  1391.  
  1392.          For HANDLER_HANGUP, the handler functions has to be declared like
  1393.          this:
  1394.  
  1395.          int hanguphandler(void)
  1396.          {
  1397.          ...
  1398.          }
  1399.  
  1400.          The hangup handler works a little different: it is called whenever
  1401.          ProBoard exits (carrier lost, sysop hung up,...). It can be used to
  1402.          perform some cleanup for your running PEX file (like closing
  1403.          files, writing data, etc..). You can install the handler at the
  1404.          start of your program and remove it before the program is
  1405.          finished.
  1406.  
  1407.  
  1408.  
  1409.  
  1410.  
  1411.  
  1412.  
  1413.  
  1414.  
  1415.  
  1416.  
  1417.  
  1418.  
  1419.  
  1420.  
  1421.  
  1422.  
  1423.  
  1424.  
  1425.  
  1426.  
  1427.  
  1428.  
  1429.  
  1430.                                       - 25 -
  1431.  
  1432.  
  1433.  
  1434.          If a handler function decides to do anything, it has to return
  1435.          HANDLED. If the handler wants to leave it up to ProBoard, it must
  1436.          return NOT_HANDLED.
  1437.  
  1438.          This asks for an example I suppose:
  1439.  
  1440.          int keyhandler(KEY k)
  1441.          {
  1442.           if(k == KEY_ALTJ)
  1443.             {
  1444.              printf("\7\rHang on %s! I'm shelling to DOS...",UserFirstName);
  1445.              MenuFunction(MENU_SHELL,"*N*Q*X*!");
  1446.              printf("I'm back!!\n");
  1447.  
  1448.              return HANDLED;
  1449.             }
  1450.            else return NOT_HANDLED;
  1451.          }
  1452.  
  1453.          main(int argc,char *argv[])
  1454.          {
  1455.           InstallHandler(HANDLER_SYSOPKEY,keyhandler);
  1456.  
  1457.           ExitTSR();    /* IMPORTANT */
  1458.          }
  1459.  
  1460.          So what does it do?  It intercepts the sysopkey-function, and
  1461.          checks if the key pressed is Alt-J. If it is, it shells to DOS
  1462.          with swapping ON, and it writes its own messages to the screen.
  1463.          When the sysop returns, the handler returns HANDLED to let
  1464.          ProBoard know that it does not have to process the key. You could
  1465.          use this example in an INIT.PEX file.
  1466.          Is this powerful or what?
  1467.  
  1468.  
  1469.  
  1470.          ──────────────────────────────────────────────────────────────────
  1471.          void RemoveHandler(int handler,function);
  1472.          ──────────────────────────────────────────────────────────────────
  1473.  
  1474.          Removes handler number <handler> which has been installed by
  1475.          InstallHandler().  <function> is the pointer to the handler that
  1476.          should be removed.
  1477.  
  1478.  
  1479.  
  1480.  
  1481.  
  1482.  
  1483.  
  1484.  
  1485.  
  1486.                                       - 26 -
  1487.  
  1488.  
  1489.  
  1490.          ──────────────────────────────────────────────────────────────────
  1491.          long MsgNum(int area, long id)
  1492.          ──────────────────────────────────────────────────────────────────
  1493.  
  1494.          Returns the message number for message 'id', in area 'area'.  For
  1495.          Hudson and *.MSG, this is identical to the message id (but DO NOT
  1496.          rely on that).  Returns a value < 1 if there is no message number
  1497.          for 'id'.
  1498.  
  1499.  
  1500.  
  1501.          ──────────────────────────────────────────────────────────────────
  1502.          long MsgId(int area, long n)
  1503.          ──────────────────────────────────────────────────────────────────
  1504.  
  1505.          Returns the message id for message number 'n', in area 'area'. For
  1506.          Hudson and *.MSG, this is identical to the message number (but DO
  1507.          NOT rely on that).  Returns a value < 1 if there is no message
  1508.          number 'n'.
  1509.  
  1510.  
  1511.  
  1512.          ──────────────────────────────────────────────────────────────────
  1513.          long HighMsg(int area)
  1514.          ──────────────────────────────────────────────────────────────────
  1515.  
  1516.          Returns the message id of the last message in the given area.
  1517.          Note: if the lastread pointer is higher than what this function
  1518.          returns, DO NOT use FirstMessage()!  The FirstMessage() function
  1519.          does not support reading past the end of the area. (if you know
  1520.          what I mean :-)
  1521.  
  1522.  
  1523.  
  1524.          ──────────────────────────────────────────────────────────────────
  1525.          long NumMsgs(int area)
  1526.          ──────────────────────────────────────────────────────────────────
  1527.  
  1528.          Returns the total number of active messages in the given area.
  1529.  
  1530.  
  1531.  
  1532.          ──────────────────────────────────────────────────────────────────
  1533.          void LocalDisplay(bool showlocal)
  1534.          ──────────────────────────────────────────────────────────────────
  1535.  
  1536.          Enables/Disables local echo of text.  A parameter of TRUE means
  1537.          "enable local display".  FALSE means "disable local display". See
  1538.          _GRAPH.CPP for an example.
  1539.  
  1540.  
  1541.  
  1542.                                       - 27 -
  1543.  
  1544.  
  1545.  
  1546.          ──────────────────────────────────────────────────────────────────
  1547.          void RemoteDisplay(bool showremote)
  1548.          ──────────────────────────────────────────────────────────────────
  1549.  
  1550.          Enables/Disables remote echo of text.  A parameter of TRUE means
  1551.          "enable remote display".  FALSE means "disable remote display".
  1552.          See _GRAPH.CPP for an example.
  1553.  
  1554.  
  1555.  
  1556.          ──────────────────────────────────────────────────────────────────
  1557.          bool RIP()
  1558.          ──────────────────────────────────────────────────────────────────
  1559.  
  1560.          Returns TRUE if RIP was detected and enabled.  FALSE if not...
  1561.  
  1562.  
  1563.  
  1564.          ──────────────────────────────────────────────────────────────────
  1565.          void ShowRIPscrip( char *name )
  1566.          ──────────────────────────────────────────────────────────────────
  1567.  
  1568.          This will send a RIP file located in the RIP directory.  No file
  1569.          extension should be given.  (.RIP is assumed)  The file will not
  1570.          be shown on the local screen.
  1571.  
  1572.  
  1573.  
  1574.          ──────────────────────────────────────────────────────────────────
  1575.          void ResetInactivity( void )
  1576.          ──────────────────────────────────────────────────────────────────
  1577.  
  1578.          Resets the internal inactivity timeout counter.  This function can
  1579.          be used when returning from a shell or after a time-consuming
  1580.          function has been called.  It will prevent the user from being
  1581.          logged off because of inactivity.
  1582.  
  1583.  
  1584.  
  1585.          ──────────────────────────────────────────────────────────────────
  1586.          bool AddTaggedFile( TAGGED_FILE *tag )
  1587.          ──────────────────────────────────────────────────────────────────
  1588.  
  1589.          Adds a file to the internal list of tagged files.  Returns TRUE if
  1590.          the was successfully added, or FALSE if the file was already
  1591.          tagged.
  1592.  
  1593.  
  1594.  
  1595.  
  1596.  
  1597.  
  1598.                                       - 28 -
  1599.  
  1600.  
  1601.  
  1602.          ──────────────────────────────────────────────────────────────────
  1603.          bool RemoveTaggedFile( TAGGED_FILE *tag )
  1604.          ──────────────────────────────────────────────────────────────────
  1605.  
  1606.          Removes a file from the internal list of tagged files.  Returns
  1607.          TRUE if the tagged file was found and deleted from the list, or
  1608.          FALSE if the tagged file was not in the list.
  1609.  
  1610.  
  1611.  
  1612.          ──────────────────────────────────────────────────────────────────
  1613.          void ClearTaggedFiles( void )
  1614.          ──────────────────────────────────────────────────────────────────
  1615.  
  1616.          Clears the internal list of tagged files (all tags are removed).
  1617.  
  1618.  
  1619.  
  1620.          ──────────────────────────────────────────────────────────────────
  1621.          bool IsTagged( TAGGED_FILE *tag )
  1622.          ──────────────────────────────────────────────────────────────────
  1623.  
  1624.          Returns TRUE if the given file is in the internal list of tagged
  1625.          files, FALSE if not.
  1626.  
  1627.  
  1628.  
  1629.          ──────────────────────────────────────────────────────────────────
  1630.          int GetTaggedFiles( TAGGED_FILE *tagarray , int maxitems )
  1631.          ──────────────────────────────────────────────────────────────────
  1632.  
  1633.          Fills the given array <tagarray> with all the files in the
  1634.          internal list of tagged files (up to a maximum of <maxitems>).
  1635.          This function returns the number of tagged files copied to the
  1636.          array <tagarray> (<= maxitems).
  1637.  
  1638.  
  1639.  
  1640.          ──────────────────────────────────────────────────────────────────
  1641.          bool PutTaggedFiles( TAGGED_FILE *tagarray , int nitems )
  1642.          ──────────────────────────────────────────────────────────────────
  1643.  
  1644.          Fills the internal list of tagged files with the files in the
  1645.          given array <tagarray>. <nitems> is the number of items in the
  1646.          array.  Returns TRUE on success, FALSE on error.
  1647.  
  1648.  
  1649.  
  1650.  
  1651.  
  1652.  
  1653.  
  1654.                                       - 29 -
  1655.  
  1656.  
  1657.  
  1658.         ┌──────────────────────────────────────────────────────────────────┐
  1659.         │ Global ProBoard Variables                                        │
  1660.         └──────────────────────────────────────────────────────────────────┘
  1661.  
  1662.          You have access to some important ProBoard system variables
  1663.          through global variables defined in PB_SDK.H.
  1664.  
  1665.  
  1666.  
  1667.          ──────────────────────────────────────────────────────────────────
  1668.          word PBVersion;
  1669.          ──────────────────────────────────────────────────────────────────
  1670.  
  1671.          The version number of ProBoard. The high byte is the major version
  1672.          number (eg. 1). The low byte is the minor version number in
  1673.          hex (eg. 0x30). So if you're using ProBoard v1.30, PBVersion will
  1674.          be set to 0x0130 .
  1675.  
  1676.  
  1677.  
  1678.          ──────────────────────────────────────────────────────────────────
  1679.          word Beta;
  1680.          ──────────────────────────────────────────────────────────────────
  1681.  
  1682.          The beta version number of ProBoard. If this number is 0xFFFF,
  1683.          it means that the release version is running. Beta numbers
  1684.          start from 1.
  1685.          For example, when running ProBoard 1.40 Beta/19, PBVersion will be
  1686.          set to 0x0140, and Beta will be set to 19.
  1687.  
  1688.  
  1689.  
  1690.          ──────────────────────────────────────────────────────────────────
  1691.          long BaudRate
  1692.          ──────────────────────────────────────────────────────────────────
  1693.  
  1694.          The current bps rate of the caller. 0 means local.
  1695.  
  1696.  
  1697.  
  1698.  
  1699.  
  1700.  
  1701.  
  1702.  
  1703.  
  1704.  
  1705.  
  1706.  
  1707.  
  1708.  
  1709.  
  1710.                                       - 30 -
  1711.  
  1712.  
  1713.  
  1714.          ──────────────────────────────────────────────────────────────────
  1715.          USER_REC * CurUser;
  1716.          ──────────────────────────────────────────────────────────────────
  1717.  
  1718.          Pointer to the current user record. You can change any of the
  1719.          field values in the record, but this will not result in any
  1720.          immediate action by ProBoard. For example, if you change the
  1721.          user's level, ProBoard will not know that you changed it, so you
  1722.          will have to tell it by calling AdjustTime();
  1723.  
  1724.          Check the file PB_SDK.H for a description of the USER_REC
  1725.          structure.
  1726.  
  1727.  
  1728.  
  1729.          ──────────────────────────────────────────────────────────────────
  1730.          int UserRecNr;
  1731.          ──────────────────────────────────────────────────────────────────
  1732.  
  1733.          The record number of the current user's record in the file
  1734.          USERS.BBS, starting from 0. This value cannot be changed.
  1735.  
  1736.  
  1737.  
  1738.          ──────────────────────────────────────────────────────────────────
  1739.          int NumLimits;
  1740.          ──────────────────────────────────────────────────────────────────
  1741.  
  1742.          The number of user levels defined in ProCFG. You can access the
  1743.          limit-values through the global array 'Limits'.  This value
  1744.          cannot be changed.
  1745.  
  1746.  
  1747.  
  1748.          ──────────────────────────────────────────────────────────────────
  1749.          LIMIT * Limits;
  1750.          ──────────────────────────────────────────────────────────────────
  1751.  
  1752.          Is an array of all user levels defined, with download and time
  1753.          limits. Check the file PB_SDK.H for information on the LIMIT
  1754.          structure.
  1755.          You are not allowed to change any values! (A good compiler should
  1756.          generate an error or warning if you try to do so)
  1757.  
  1758.  
  1759.  
  1760.  
  1761.  
  1762.  
  1763.  
  1764.  
  1765.  
  1766.                                       - 31 -
  1767.  
  1768.  
  1769.  
  1770.          ──────────────────────────────────────────────────────────────────
  1771.          char * LoginDate;
  1772.          char * LoginTime;
  1773.          ──────────────────────────────────────────────────────────────────
  1774.  
  1775.          This is the login date & time of the current user.
  1776.  
  1777.            LoginDate[0] : Day portion of login date
  1778.            LoginDate[1] : Month portion of login date
  1779.            LoginDate[2] : Year portion of login date (00-99)
  1780.            LoginTime[0] : Hour portion of login time
  1781.            LoginTime[1] : Minute portion of login time
  1782.            LoginTime[2] : Second portion of login time
  1783.  
  1784.  
  1785.  
  1786.          ──────────────────────────────────────────────────────────────────
  1787.          bool NetEntered;
  1788.          bool EchoEntered;
  1789.          ──────────────────────────────────────────────────────────────────
  1790.   {}
  1791.          These READ-ONLY variables tell you if netmail and/or echomail has
  1792.          been entered during this session.
  1793.  
  1794.  
  1795.  
  1796.          ──────────────────────────────────────────────────────────────────
  1797.          int NumUsers;
  1798.          ──────────────────────────────────────────────────────────────────
  1799.  
  1800.          This READ-ONLY variable is the number of users currently available
  1801.          in the file USERS.BBS.
  1802.  
  1803.  
  1804.  
  1805.          ──────────────────────────────────────────────────────────────────
  1806.          int NodeNumber;
  1807.          ──────────────────────────────────────────────────────────────────
  1808.  
  1809.          This READ-ONLY variable is the current node number.
  1810.  
  1811.  
  1812.  
  1813.  
  1814.  
  1815.  
  1816.  
  1817.  
  1818.  
  1819.  
  1820.  
  1821.  
  1822.                                       - 32 -
  1823.  
  1824.  
  1825.  
  1826.          ──────────────────────────────────────────────────────────────────
  1827.          char * CurMenu;
  1828.          char * UserFirstname;
  1829.          char * PrevUser;
  1830.          char * StartupPath;
  1831.          char * SysPath;
  1832.          char * PageReason;
  1833.          ──────────────────────────────────────────────────────────────────
  1834.  
  1835.          CurMenu       : Current menu name
  1836.          UserFirstName : First name of current user
  1837.          PrevUser      : Name of previous user
  1838.          StartupPath   : Name of the directory where ProBoard was started
  1839.                          from (with trailing '\')
  1840.          SysPath       : Name of the ProBoard system directory (with
  1841.                          trailing '\')
  1842.          PageReason    : Reason for paging the sysop (as entered by the
  1843.                          user)
  1844.  
  1845.          These are READ-ONLY strings! (except PageReason)
  1846.  
  1847.  
  1848.  
  1849.          ──────────────────────────────────────────────────────────────────
  1850.          word * PageCount;
  1851.          ──────────────────────────────────────────────────────────────────
  1852.  
  1853.          POINTER to the number of sysop pages done by the user.  This value
  1854.          can be changed by changing the unsigned integer pointed to by
  1855.          'PageCount'.
  1856.  
  1857.  
  1858.  
  1859.          ──────────────────────────────────────────────────────────────────
  1860.          CONFIG * Config;
  1861.          ──────────────────────────────────────────────────────────────────
  1862.  
  1863.          A pointer to the current ProBoard configuration structure. See the
  1864.          file PB_SDK.H for a description of the CONFIG structure.
  1865.  
  1866.  
  1867.  
  1868.  
  1869.  
  1870.  
  1871.  
  1872.  
  1873.  
  1874.  
  1875.  
  1876.  
  1877.  
  1878.                                       - 33 -
  1879.  
  1880.  
  1881.  
  1882.          ┌────────────────────────────────────────────────────────────────┐
  1883.          │ Special-purpose PEX-files                                      │
  1884.          └────────────────────────────────────────────────────────────────┘
  1885.  
  1886.          Several pex-files will be loaded automatically (if present). They
  1887.          perform certain actions like edit a message, set up handlers, etc.
  1888.  
  1889.                INIT.PEX      : Will be loaded and executed before any I/O
  1890.                                has been done.  Use this to set up any
  1891.                                handlers (sysopkey handlers, ...)
  1892.  
  1893.                INIT_1.PEX -
  1894.                INIT_9.PEX    : Is the same as INIT.PEX, but will be loaded
  1895.                                in the order of the numbers. So you can have
  1896.                                up to 10 initialization pex-files.
  1897.  
  1898.                _LOGIN.PEX    : Is run instead of the normal login
  1899.                                procedure.  See the section explaining this
  1900.                                PEX for more information.
  1901.  
  1902.                LOGIN.PEX     : No longer supported!
  1903.  
  1904.                BIRTHDAY.PEX  : Is run after showing NEWS.ANS/ASC if today
  1905.                                is the user's birthday.
  1906.  
  1907.                NEWUSER.PEX   : Is run before the file NEWUSER.A?? is shown.
  1908.  
  1909.                NEWUSER1.PEX  : Is run before the file NEWUSER1.A?? is
  1910.                                shown.
  1911.  
  1912.                NEWUSER2.PEX  : Is run before the file NEWUSER2.ANS/ASC is
  1913.                                shown.
  1914.  
  1915.                WELCOME.PEX   : Is run before the file WELCOME.ANS/ASC is
  1916.                                shown
  1917.  
  1918.                WELCOMEx.PEX  : Is run before the file WELCOMEx.ANS/ASC is
  1919.                                shown (x = 1 to 9)
  1920.  
  1921.                SECxx.PEX     : Executed when a user with security level xx
  1922.                                logs in. Is run before SECxx.ANS/ASC is
  1923.                                shown.
  1924.  
  1925.                EXPIRED.PEX   : Is run before EXPIRED.ANS/ASC is shown, and
  1926.                                after a user's level is lowered because the
  1927.                                subscription date was reached. ProBoard will
  1928.                                send one parameter to this PEX: the original
  1929.                                level, before it was changed by ProBoard.
  1930.  
  1931.                GOODBYE.PEX   : Is run before GOODBYE.ANS is displayed.
  1932.  
  1933.  
  1934.                                       - 34 -
  1935.  
  1936.  
  1937.  
  1938.                GOODBYE2.PEX  : Is run after GOODBYE.ANS is displayed.
  1939.  
  1940.                MSGED.PEX     : Is a replacement of the built-in message
  1941.                                editor. It will be executed with no
  1942.                                parameters. The message that you create has
  1943.                                to be written to a file called MSGTMP.
  1944.                                ProBoard will then read this file and create
  1945.                                a message from it. To let ProBoard know that
  1946.                                the user has aborted a message, delete
  1947.                                MSGTMP.
  1948.  
  1949.                FSED.PEX      : Is similar to MSGED.PEX, but will be
  1950.                                executed if the user has selected the
  1951.                                fullsrceen editor. It works the same way as
  1952.                                MSGED.PEX, but ProBoard will create a MSGTMP
  1953.                                file with the original message if a user is
  1954.                                replying to a message.
  1955.  
  1956.  
  1957.  
  1958.  
  1959.  
  1960.  
  1961.  
  1962.  
  1963.  
  1964.  
  1965.  
  1966.  
  1967.  
  1968.  
  1969.  
  1970.  
  1971.  
  1972.  
  1973.  
  1974.  
  1975.  
  1976.  
  1977.  
  1978.  
  1979.  
  1980.  
  1981.  
  1982.  
  1983.  
  1984.  
  1985.  
  1986.  
  1987.  
  1988.  
  1989.  
  1990.                                       - 35 -
  1991.  
  1992.  
  1993.  
  1994.  
  1995.          ┌────────────────────────────────────────────────────────────────┐
  1996.          │ Using the _LOGIN PEX                                           │
  1997.          └────────────────────────────────────────────────────────────────┘
  1998.  
  1999.           (Caution: this feature was added at the last moment, so it hasn't
  2000.           been tested very well, but as far as I know, it should work as
  2001.           described here.  The description is also very brief, for the same
  2002.           reason)
  2003.  
  2004.           By writing a _LOGIN.PEX, ProBoard allows you to replace the
  2005.           normal login procedure (not including the new user procedure)
  2006.           with your own.  It is the PEX's responsibility to check for
  2007.           validity of the name entered and to do password checking!
  2008.  
  2009.           Once you determined the record number of the user, you have to
  2010.           call the function SetUser() with the record number as parameter,
  2011.           and exit the PEX immediately.
  2012.  
  2013.           If the user is not in the user database yet, you should exit
  2014.           without calling SetUser(), and set the name that was entered by
  2015.           the user in a memory region supplied by ProBoard to your PEX as
  2016.           the only parameter.  This parameter is a 'dword' in decimal form,
  2017.           so you have to convert it to a pointer using the following
  2018.           procedure:
  2019.  
  2020.           /*----------------------------*/
  2021.           char *pName;
  2022.           dword dwName = 0;
  2023.           char *s;
  2024.  
  2025.           for(s = argv[1] ; *s ; s++)
  2026.              dwName = l_mul(dwName,10L) + (dword)(*s - '0');
  2027.  
  2028.           pName = (char *)dwName;
  2029.           /*----------------------------*/
  2030.  
  2031.  
  2032.  
  2033.  
  2034.  
  2035.  
  2036.  
  2037.  
  2038.  
  2039.  
  2040.  
  2041.  
  2042.  
  2043.  
  2044.  
  2045.  
  2046.  
  2047.                                       - 36 -
  2048.